#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# This program is free software; you can redistribute it and/or modify  
# it under the terms of the GNU General Public License as published by  
# the Free Software Foundation; either version 2 of the License, or     
# (at your option) any later version.                                   
#                                                                         
# A copy of the license can be found in the license.txt file supplied   
# with this software or at: http://www.gnu.org/copyleft/gpl.html       
#


import xml.dom.minidom

from columnfamilystore import ColumnFamilyStore
from columnfamily import ColumnFamily

from rowmutator import RowMutator

from commitlog import CommitLog

from xmlhelper import XmlHelper

class   Table(object) :
    
    @staticmethod
    def open(table_name, schema_xml) :
        '''create table object with schema

        XML Schema of table :
        <?xml version="1.0" encoding="UTF-8" ?>
        <database>
            <table name="page">
                <column-families>
                    <column-family>
                        <id> 1 </id>
                        <name> data </name>
                    </column-family>
                    <column-family>
                        <id> 2 </id>
                        <name> attr </name>
                    </column-family>
                </column-families>
            </table>
            <table name="cache">
                <column-families>
                    <column-family>
                        <id> 1 </id>
                        <name> data </name>
                    </column-family>
                </column-families>
            </table>
        </database>
        '''
        if not table_name or not schema_xml :
            return None

        dom = xml.dom.minidom.parseString(schema_xml)
        node_tables = XmlHelper.getChildrenByPath(dom, 'database/table')
        node_table = None
        for node in node_tables :
            name = node.getAttribute('name')
            if name == table_name :
                node_table = node
                break
        if node_table is None :
            return None

        table = Table(table_name)

        node_cfs = XmlHelper.getChildrenByPath(node_table, 'column-families/column-family')
        for node in node_cfs :
            id = XmlHelper.getChildNodeTextByPath(node, 'id')
            name = XmlHelper.getChildNodeTextByPath(node, 'name')

            table.setColumnFamilyName(int(id), name.strip())

        return table
        ## open()

    def __init__(self, name) :
        self.name = name
        
        # id-name of column-family
        self._cf_id_2_name = {}

        # name-id of column-family
        self._cf_name_2_id = {}

        # list of column-family-store
        self._column_family_stores = {}
        ## __init__()

    def __del__(self) :
        self._cf_id_2_name = {}
        self._cf_name_2_id = {}
        self._column_family_stores = {}
        ## __del__()

    def setColumnFamilyName(self, cf_id, cf_name) :
        if not cf_id or not cf_name : return
        self._cf_id_2_name[ cf_id ] = cf_name
        self._cf_name_2_id[ cf_name ] = cf_id

        self._column_family_stores[ cf_name ] = ColumnFamilyStore(self.name, cf_name)
        ## setColumnFamilyName()

    def getColumnFamilyNames(self) :
        return self._cf_name_2_id.keys()
        ## getColumnFamilyNames()

    def getColumnFamilyName(self, cf_id) :
        if cf_id in self._cf_id_2_name :
            return self._cf_id_2_name[ cf_id ]

        return None
        ## getColumnFamilyName()

    def getColumnFamilyId(self, cf_name) :
        if cf_name in self._cf_name_2_id :
            return self._cf_name_2_id[ cf_name ]

        return 0
        ## getColumnFamilyId()

    def getColumnFamilyStore(self, cf_name) :
        if cf_name not in self._column_family_stores :
            raise RuntimeError, 'No store for column family "%s".' % cf_name
        return self._column_family_stores[ cf_name ]
        ## getColumnFamilyStore()

    def getRowMutator(self, key) :
        mutator = RowMutator(self, key)
        return mutator
        ## getRowMutator()


    def apply(self, row) :
        '''commit row mutation
        '''
        clog_ctx = CommitLog.instance().add(row)
        
        row_key = row.key
        for cf in row.getColumnFamilies() :
            cf_store = self.getColumnFamilyStore(cf.name)
            cf_store.apply(row_key, cf, clog_ctx)
        ## apply()

    ## class Table()



